import { Loading } from 'element-ui'
import Vue from 'vue'

const vue = new Vue()

/**
 * vue-resource 封装底层UI组件
 * @module app/common
 * @author 韩晗
 */
// 全屏公用loading实例
let fullscreenLoading

/**
 * 由屏幕上方滑下来的提示框
 * @param {string} text 提示内容
 * @param {string} type 弹窗Icon及样式类别（success|warning|info|error）
 * @param {boolean} showClose 是否显示关闭按钮，默认显示
 * @param {number} duration 持续时间，默认3秒
 * @returns {void}
 */
const message = (text, type = 'info', showClose = true, duration = 3000) => {
  vue.$message({
    type: type,
    message: text,
    duration: duration,
    showClose: showClose
  })
}
/**
 * 成功提示框
 * @param {string} text 提示内容
 * @param {boolean} showClose 是否显示关闭按钮，默认显示
 * @param {number} duration 持续时间，默认3秒
 * @returns {void}
 */
const successMessage = (text, showClose = true, duration = 3000) => {
  message(text, 'success', showClose, duration)
}
/**
 * 错误提示框
 * @param {string} text 提示内容
 * @param {boolean} showClose 是否显示关闭按钮，默认显示
 * @param {number} duration 持续时间，默认3秒
 * @returns {void}
 */
const errorMessage = (text, showClose = true, duration = 3000) => {
  message(text, 'error', showClose, duration)
}
/**
 * 警告提示框
 * @param {string} text 提示内容
 * @param {boolean} showClose 是否显示关闭按钮，默认显示
 * @param {number} duration 持续时间，默认3秒
 * @returns {void}
 */
const warningMessage = (text, showClose = true, duration = 3000) => {
  message(text, 'warning', showClose, duration)
}

/**
 * 侧边通知提醒
 * @param {string} title 标题
 * @param {string|object} msg 说明文字|消息对象
 * @param {string} type 主题样式，如果不在可选值内将被忽略 （success|warning|info|error）
 * @param {boolean} showClose 是否显示关闭按钮，默认true
 * @param {number} duration 持续时间，默认4.5秒
 * @returns {void}
 */
const notify = (title, msg, type = 'info', showClose = true, duration = 4500) => {
  // 如果全屏loading实例不为空，则关闭这个实例
  if (fullscreenLoading) {
    fullscreenLoading.close()
  }

  // 通过对msg的参数验证，执行不同的notice逻辑
  // ① 如果msg是字符串，且字符串中有html元素标记，则按html显示
  // ② 如果msg是字符串，但字符串中没有html元素标记，则按text显示
  // ③ 如果msg是Json Object，则必须符合如下结构
  // msg = {
  //  data: {
  //     errCode: "ST1586",
  //     message: "稿件未被加锁，处于非可操作状态"
  //  },
  //  err_code: 99,
  //  err_msg: "保存失败"
  // }
  let message = ''; let isHtmlString = false
  if (typeof msg === 'string') {
    const tagReg = /<[a-z]+\d?\s*[^<>]*>.*/i
    if (tagReg.test(msg)) {
      message = msg
      isHtmlString = true
    } else {
      message = msg
    }
  } else {
    if (msg.err_msg) {
      message = msg.err_msg
    }
    if (msg.data && msg.data.message) {
      message += '<br/>' + msg.data.message
    }
    if (msg.data && msg.data.errCode) {
      message += '<br/>' + msg.data.errCode
    }
    isHtmlString = true
  }

  vue.$notify({
    type: type,
    title: title,
    message: message,
    dangerouslyUseHTMLString: isHtmlString, // 是否将message属性作为HTML片段处理,默认false
    duration: duration,
    position: 'top-right', // 出现的位置（top-right|top-left|bottom-right|bottom-left）
    showClose: showClose,
    customClass: `el-message--${type}`, // 自定义class名，用于修改颜色样式
    onClose: () => {}, // 关闭回调
    onClick: () => {}, // 点击回调
    offset: 0
  })
}
/**
 * 成功侧边通知提醒
 * @param {string} text 说明文字
 * @param {boolean} showClose 是否显示关闭按钮，默认true
 * @param {number} duration 持续时间，默认4.5秒
 * @returns {void}
 */
const successNotify = (text, showClose = true, duration = 4500) => {
  notify('成功', text, 'success', showClose, duration)
}
/**
 * 警告侧边通知提醒
 * @param {string} text 说明文字
 * @param {boolean} showClose 是否显示关闭按钮，默认true
 * @param {number} duration 持续时间，默认4.5秒
 * @returns {void}
 */
const warningNotify = (text, showClose = true, duration = 4500) => {
  notify('警告', text, 'warning', showClose, duration)
}
/**
 * 错误侧边通知提醒
 * @param {string} text 说明文字
 * @param {boolean} showClose 是否显示关闭按钮，默认true
 * @param {number} duration 持续时间，默认4.5秒
 * @returns {void}
 */
const errorNotify = (text, showClose = true, duration = 4500) => {
  notify('错误', text, 'error', showClose, duration)
}
/**
 * 关闭所有侧边通知
 * @return {void}
 */
const notifyCloseAll = () => {
  vue.$notify.closeAll()
}

/**
 * 消息提示
 * @param {string} mesg 消息，可以是html
 * @param {function} cb 点击【确定】按钮后的回调
 * @return {void}
 */
const Alert = (mesg, cb = () => {}) => {
  vue.$alert(mesg, '提示', {
    confirmButtonText: '确定',
    dangerouslyUseHTMLString: true,
    callback: cb
  })
}

/**
 * 确认消息弹窗
 * @param {string} mesg 消息，可以是html
 * @param {string} confirmButtonText 确认按钮的文本
 * @param {string} cancelButtonText 取消按钮的文本
 * @return {Promise} pomise对象
 *      当点击【确定】按钮是，执行then中的函数，当点击【取消】时，执行catch里面的函数
 */
const Confirm = (mesg, confirmButtonText = '确定', cancelButtonText = '取消') => {
  return vue.$confirm(mesg, '确认', {
    type: 'warning',
    dangerouslyUseHTMLString: true,
    cancelButtonText: cancelButtonText,
    confirmButtonText: confirmButtonText
  })
}

/**
 * 自定义消息盒子
 * @param {string} title 标题
 * @param {string} type 类型，就是mesg前面的icon，取值范围：success|info|warning|error，传空字符串代表没有不需要图标
 * @param {string} mesg 消息，可以是html
 * @param {string} confirmButtonText 确认（蓝色）按钮的文本，如果不需要，可以传空值
 * @param {string} cancelButtonText 取消（灰色）按钮的文本，如果不需要，可以传空值
 * @return {Promise} pomise对象
 *      当点击【确定】按钮是，执行then中的函数，当点击【取消】时，执行catch里面的函数
 */
const MesgBox = (title = '消息', type = 'info', mesg = '', confirmButtonText = '确定', cancelButtonText = '取消') => {
  const options = {
    title: title,
    type: type,
    message: mesg,
    showConfirmButton: false,
    showCancelButton: false,
    dangerouslyUseHTMLString: true,
    distinguishCancelAndClose: true
  }
  if (!!confirmButtonText && confirmButtonText !== '') {
    options.confirmButtonText = confirmButtonText
    options.showConfirmButton = true
  }
  if (!!cancelButtonText && cancelButtonText !== '') {
    options.cancelButtonText = cancelButtonText
    options.showCancelButton = true
  }
  return vue.$msgbox(options)
}

/**
 * 全屏loading
 * @param {string} text loading显示的文本提示信息
 * @param {boolean} isOn true开启loading false关闭loading
 * @returns {void}
 */
const FullscreenLoading = (text = '', isOn = false) => {
  const options = { text: text }
  if (isOn) {
    fullscreenLoading = Loading.service(options)
  } else if (fullscreenLoading) {
    fullscreenLoading.close()
  }
}

/**
 * 通用loading
 * @param {string} selector loading层覆盖的元素选择器
 * @param {string} text loading显示的文本提示信息
 * @param {boolean} isOn true开启loading false关闭loading
 * @returns {Object} loading实例，可通过close()方法，手动关闭
 */
const CommonLoading = (selector = '', text = '', isOn = false) => {
  // 全屏loading
  if (selector === '') {
    FullscreenLoading(isOn)
    return fullscreenLoading
  }

  // 其他
  const options = { target: selector, text: text }
  return Loading.service(options)
}

/**
 * 延时关闭窗口
 * @param {Function} callback 关闭前回调
 * @param {number} time 关闭延迟时间
 * @returns {void}
 */
const closeWindow = (callback, time = 200) => {
  setTimeout(() => {
    callback && callback()
    window.close()
  }, time)
}

/**
 *  建议输出名为noticeUtil
 */
export default {
  msg: message,
  errorMsg: errorMessage,
  successMsg: successMessage,
  warningMsg: warningMessage,

  notify: notify,
  errorNotify: errorNotify,
  successNotify: successNotify,
  warningNotify: warningNotify,
  notifyCloseAll: notifyCloseAll,

  alert: Alert,
  confirm: Confirm,
  mesgBox: MesgBox,

  loading: CommonLoading,
  fullscreenLoading: FullscreenLoading,

  closeWindow: closeWindow
}
